//go:build wireinject

package msg

import (
	"gitee.com/flycash/simple-im/internal/api/http"
	"gitee.com/flycash/simple-im/internal/event/msg"
	"gitee.com/flycash/simple-im/internal/event/msg/consumer"
	"gitee.com/flycash/simple-im/internal/repository"
	"gitee.com/flycash/simple-im/internal/repository/dao"
	"gitee.com/flycash/simple-im/internal/service"
	"gitee.com/flycash/simple-im/internal/test/ioc"
	"github.com/ecodeclub/mq-api"
	"github.com/google/wire"
)

var (
	baseSet = wire.NewSet(
		ioc.InitDBAndTables,
		ioc.InitMQ,
	)
	msgSvcSet = wire.NewSet(
		dao.NewGORMMessageDAO,
		dao.NewGORMChannelDAO,
		dao.NewGORMChannelMemberDAO,
		repository.NewMessageRepository,
		repository.NewChannelRepository,
		initProducer,
		service.NewMessageService,
		http.NewMessageHandler,
	)
	channelSvcSet = wire.NewSet(
		dao.NewGORMUserChannelReadRecordDAO,
		repository.NewChannelMemberReadRecordRepo,
		service.NewChannelService,
		http.NewChannelHandler,
	)
)

type App struct {
	MsgHdl     *http.MessageHandler
	ChannelHdl *http.ChannelHandler
	Consumer   *consumer.Consumer
}

func initProducer(testMq mq.MQ) msg.Producer {
	pro, err := testMq.Producer("test_topic")
	if err != nil {
		panic(err)
	}
	return msg.NewProducer(pro, "test_topic")
}

func InitApp() *App {
	wire.Build(
		baseSet,
		msgSvcSet,
		channelSvcSet,
		initConsumer,
		wire.Struct(new(App), "*"),
	)
	return new(App)
}

func initConsumer(mq mq.MQ, svc service.MessageService) *consumer.Consumer {
	// 这里的配置从配置文件中读取，这里方便测试就直接写在代码中
	return consumer.NewConsumer("im_async_group", mq, "im_async_topic", 1, svc)
}
